home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.4)
-
- import os
- import sys
- import time
- import socket
- import poplib
- import imaplib
- import threading
- import win32process
- from win32api import GetConsoleTitle
- from win32api import GetCurrentThread
- from win32api import error as win32api_error
- from spamexperts.Options import options
- from se_config import spamexpertsConfig
- from spamexperts.OptionsClass import IS_HAM, IS_SPAM, IS_UNSURE
- from spamexperts import se_state
- state = se_state.state
- from spamexperts import server
- VIEW_SPAM = 0
- VIEW_UNSURE = 1
- VIEW_HAM = 2
- VIEW_BLACK = 3
- VIEW_WHITE = 4
-
- class Message(object):
-
- def __init__(self, sender = '', recipient = '', subject = '', body = ''):
- self.sender = sender
- self.recipient = recipient
- self.subject = subject
- self.body = body
-
-
-
- class SEModel(object):
- views = []
-
- def __init__(self, mutex):
- self.started = False
- self.ham_list = { }
- self.unsure_list = { }
- self.spam_list = { }
- self.white_list = { }
- self.black_list = { }
- self.filter_spam = ''
- self.filter_unsure = ''
- self.filter_ham = ''
- self.added_ham = []
- self.added_unsure = []
- self.added_spam = []
- self.removed_ham = []
- self.removed_unsure = []
- self.removed_spam = []
- self.threads = []
- self.lsp_on = state.isLSPEnabled()
- self.updating = False
- self.settings = spamexpertsConfig
- self.state = state
- self.state.platform_mutex = mutex
- self.exit_func = None
- self.exit_args = None
- self.exit_kwargs = None
-
-
- def init(self, tray):
- '''Initialise the model.'''
- self.tray = tray
- state.model_notifier = tray
- state.init()
- self.active = VIEW_SPAM
- self.server_thread = threading.Thread(target = server.start, args = (tray,))
- self.server_thread.setDaemon(True)
- self.server_thread.start()
- self.periodic_thread = threading.Thread(target = self.periodic)
- self.periodic_thread.setDaemon(True)
- self.periodic_thread.start()
- self.running = True
- self.initiate_check = False
-
-
- def periodic(self):
- below_normal = win32process.THREAD_PRIORITY_BELOW_NORMAL
- win32process.SetThreadPriority(GetCurrentThread(), below_normal)
- pop3 = pop3
- import spamexperts
- imap4 = imap4
- import spamexperts
- self.retriever = pop3.POPRetriever()
- self.imap_filter = imap4.IMAPFilter()
- self.retriever.state = state
- self.imap_filter.state = state
- queue = state.reclassifier.processing_queue
- self.retriever.processing_queue = queue
- self.imap_filter.processing_queue = queue
- breather = 0.050000000000000003
- while True:
- self.initiate_check = False
- if server.stop_server:
- break
-
- if self.settings.enable_periodic and self.settings.period and self.settings.block_spam:
- for connection in self.settings.periodic:
- (server_, port, user, pass_, proto, use_ssl) = connection
- if proto == 'pop3':
- self.periodic_pop3(server_, port, user, pass_, use_ssl)
- elif proto == 'imap4':
- self.periodic_imap4(server_, port, user, pass_, use_ssl)
- else:
- print >>sys.stderr, 'Unknown protocol.'
- time.sleep(breather)
-
- for unused in xrange(self.settings.period * 600 - int(breather * len(self.settings.periodic))):
- time.sleep(0.10000000000000001)
- if server.stop_server or self.initiate_check:
- break
- continue
-
- time.sleep(1)
- if options[('globals', 'verbose')]:
- print 'Closed periodic thread.'
-
-
-
- def periodic_imap4(self, server_, port, user, pass_, use_ssl):
- account = '%s_%s_IMAP' % (user, server_)
- if not pass_:
- if options[('globals', 'verbose')]:
- print "Don't know password for", account, 'yet, skipping.'
-
- return None
-
-
- try:
- if use_ssl:
- i = imaplib.IMAP4_SSL(server_, port)
- else:
- i = imaplib.IMAP4(server_, port)
- except Exception:
- e = None
- print >>sys.stderr, "Can't do automatic login", str(e)
- return None
-
- user = user.strip('"')
- pass_ = pass_.strip('"')
-
- try:
- i.login(user, pass_)
- except (imaplib.IMAP4.error, socket.error):
- e = None
- print >>sys.stderr, 'Could not login to IMAP server', user, server_
- print >>sys.stderr, str(e)
- return None
-
- self.imap_filter.current_account = account
- state.open_remote_connections.append(account)
- state.proxies.append(self.imap_filter)
- self.imap_filter.load_folders_to_filter()
- if options[('globals', 'verbose')]:
- print 'Initiating automatic delete', account, time.asctime(time.localtime())
-
-
- try:
- self.imap_filter.expungeMessages(i)
- except KeyError:
- print "Don't know about", account, 'yet; skipping.'
- i.logout()
- state.open_remote_connections.remove(account)
- state.proxies.remove(self.imap_filter)
- return None
-
- if options[('globals', 'verbose')]:
- print 'Initiating automatic', account, time.asctime(time.localtime())
-
- self.imap_filter.updateMessageDatabase(i)
- self.imap_filter.close()
- if options[('globals', 'verbose')]:
- print 'Automatic complete', account, time.asctime(time.localtime())
-
-
-
- def periodic_pop3(self, server_, port, user, pass_, use_ssl):
- account = '%s_%s_POP' % (user, server_)
- if not pass_:
- if options[('globals', 'verbose')]:
- print "Don't know password for", account, 'yet, skipping.'
-
- return None
-
- pop3 = pop3
- import spamexperts
- if use_ssl:
- pop_class = pop3.POP3_SSL
- else:
- pop_class = pop3.POP3
-
- try:
- self.retriever.remote_server = pop_class(state.logFile, server_, port)
- except Exception:
- e = None
- print >>sys.stderr, "Can't do automatic login", str(e)
- return None
-
- self.retriever.serverName = server_
-
- try:
- self.retriever.remote_server.user(user)
- except poplib.error_proto:
- e = None
- print >>sys.stderr, "Can't do automatic login (user)", str(e)
- return None
-
-
- try:
- self.retriever.remote_server.pass_(pass_)
- except poplib.error_proto:
- e = None
- print >>sys.stderr, "Can't do automatic login (pass)", str(e)
- return None
-
- self.retriever.current_account = account
- self.state.open_remote_connections.append(self.retriever.current_account)
- state.reclassifier.current_account = account
- state.proxies.append(self.retriever)
- if options[('globals', 'verbose')]:
- print 'Initiating automatic delete', account, time.asctime(time.localtime())
-
-
- try:
- self.retriever.delete_messages(self.retriever.remote_server)
- except KeyError:
- print "Don't know about", account, 'yet; skipping.'
- self.retriever.remote_server.quit()
- state.proxies.remove(self.retriever)
- state.open_remote_connections.remove(account)
- self.retriever.close()
- return None
- except socket.error:
- e = None
- print 'Error occured during periodic deletion', str(e)
- state.proxies.remove(self.retriever)
- state.open_remote_connections.remove(account)
- self.retriever.close()
- return None
-
- if options[('globals', 'verbose')]:
- print 'Initiating automatic', account, time.asctime(time.localtime())
-
-
- try:
- self.retriever.retrieveMessages()
- except Exception:
- e = None
- print 'Error occured during periodic retrieval', str(e)
- state.proxies.remove(self.retriever)
- state.open_remote_connections.remove(account)
- self.retriever.close()
- return None
-
- self.retriever.close()
- if options[('globals', 'verbose')]:
- print 'Automatic complete', account, time.asctime(time.localtime())
-
-
-
- def AddView(self, view):
- if view not in self.views:
- self.views.append(view)
-
-
-
- def UpdateViews(self, refresh = False):
- self.updating = True
- self._GetHam(refresh)
- self._GetUnsure(refresh)
- self._GetSpam(refresh)
- for view in self.views:
- view.UpdateView(self)
-
- self.updating = False
-
-
- def AlreadyOn(self):
- return self.started
-
-
- def OkToStart(self):
- if options[('pop3proxy', 'remote_servers')] and options[('imap4proxy', 'remote_servers')] or self.lsp_on:
- return (True, _(''))
-
- return (False, 'LSP is not registered.')
-
-
- def set_exit_action(self, func, args, kwargs):
- self.exit_func = func
- self.exit_args = args
- self.exit_kwargs = kwargs
-
-
- def Exit(self, callback = None):
- if options[('globals', 'verbose')]:
- print 'Waiting for other threads...'
-
- for thread in self.threads:
- thread.join()
-
- state.quit = True
- server.stop(callback)
- if hasattr(self, 'periodic_thread'):
- if options[('globals', 'verbose')]:
- print 'Waiting for periodic thread to finish...'
-
- self.periodic_thread.join()
-
- if hasattr(self, 'server_thread'):
- if options[('globals', 'verbose')]:
- print 'Waiting for asyncore to finish...'
-
- self.server_thread.join()
- if options[('globals', 'verbose')]:
- print 'Asyncore is finished.'
-
-
- self.running = False
- if self.exit_func:
- self.exit_func(*self.exit_args, **self.exit_kwargs)
-
- print 'Model is closed.'
-
-
- def StartStop(self):
- self.UpdateViews()
-
-
- def SetActive(self, view):
- self.active = view
- self.filter_spam = self.filter_ham = self.filter_unsure = ''
- self.UpdateViews()
-
-
- def _GetSpam(self, refresh = False):
- ret = { }
- if refresh:
- self._SEModel__ham = state.getHamMessagesHeaders()
- self._SEModel__unsure = state.getUnsureMessagesHeaders()
- self._SEModel__spam = state.getSpamMessagesHeaders()
-
- for key, item in self._SEModel__spam.items():
- (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
- if msgid not in self.removed_spam:
- ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
- continue
-
- others = self._SEModel__ham.items()
- others.extend(self._SEModel__unsure.items())
- for key, item in others:
- (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
- if msgid in self.added_spam:
- ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
- continue
-
- self.spam_list = ret
-
-
- def GetSpam(self):
- filter_spam = self.filter_spam.strip().lower()
- filtered_spam = _[1]
- return dict(filtered_spam)
-
-
- def _GetHam(self, refresh = False):
- ret = { }
- if refresh:
- self._SEModel__ham = state.getHamMessagesHeaders()
- self._SEModel__unsure = state.getUnsureMessagesHeaders()
- self._SEModel__spam = state.getSpamMessagesHeaders()
-
- for key, item in self._SEModel__ham.items():
- (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
- if msgid not in self.removed_ham:
- ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
- continue
-
- others = self._SEModel__spam.items()
- others.extend(self._SEModel__unsure.items())
- for key, item in others:
- (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
- if msgid in self.added_ham:
- ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
- continue
-
- self.ham_list = ret
-
-
- def GetHam(self):
- filter_ham = self.filter_ham.strip().lower()
- filtered_ham = _[1]
- return dict(filtered_ham)
-
-
- def _GetUnsure(self, refresh = False):
- ret = { }
- if refresh:
- self._SEModel__ham = state.getHamMessagesHeaders()
- self._SEModel__unsure = state.getUnsureMessagesHeaders()
- self._SEModel__spam = state.getSpamMessagesHeaders()
-
- for key, item in self._SEModel__unsure.items():
- (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
- if msgid not in self.removed_unsure:
- ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
- continue
-
- others = self._SEModel__spam.items()
- others.extend(self._SEModel__ham.items())
- for key, item in others:
- (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
- if msgid in self.added_unsure:
- ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
- continue
-
- self.unsure_list = ret
-
-
- def GetUnsure(self):
- filter_unsure = self.filter_unsure.strip().lower()
- filtered_unsure = _[1]
- return dict(filtered_unsure)
-
-
- def GetMessage(self, msgid, klass):
- if msgid:
- (msgfrom, msgto, msgsubject, body) = state.getMessage(str(msgid[3]), klass)
- return Message(msgfrom, msgto, msgsubject, body)
- else:
- return Message()
-
-
- def MoveToSpam(self, from_, messages):
- '''Move messages to spam.
-
- messages should be an iterable of (msgfrom, emailsubject,
- emaildate, msgid).
- '''
- idlist = [ str(item[3]) for item in messages ]
- print 'move from', from_, 'to spam', idlist
- for msg_info in messages:
- if from_ == IS_HAM:
- self.removed_ham.append(msg_info[3])
- elif from_ == IS_UNSURE:
- self.removed_unsure.append(msg_info[3])
-
- if msg_info[3] in self.removed_spam:
- self.removed_spam.remove(msg_info[3])
-
- self.added_spam.append(msg_info[3])
- if msg_info[3] in self.added_ham:
- self.added_ham.remove(msg_info[3])
-
- if msg_info[3] in self.added_unsure:
- self.added_unsure.remove(msg_info[3])
- continue
-
- self.UpdateViews()
- state.moveAndTrainMessages(idlist, from_, IS_SPAM)
-
-
- def MoveToHam(self, from_, messages):
- '''Move messages to ham.
-
- messages should be an iterable of (msgfrom, emailsubject,
- emaildate, msgid).
- '''
- idlist = [ str(item[3]) for item in messages ]
- print 'move from', from_, 'to ham', idlist
- for msg_info in messages:
- if from_ == IS_SPAM:
- self.removed_spam.append(msg_info[3])
- elif from_ == IS_UNSURE:
- self.removed_unsure.append(msg_info[3])
-
- if msg_info[3] in self.removed_ham:
- self.removed_ham.remove(msg_info[3])
-
- self.added_ham.append(msg_info[3])
- if msg_info[3] in self.added_spam:
- self.added_spam.remove(msg_info[3])
-
- if msg_info[3] in self.added_unsure:
- self.added_unsure.remove(msg_info[3])
- continue
-
- self.UpdateViews()
- state.moveAndTrainMessages(idlist, from_, IS_HAM)
-
-
- def MoveToUnsure(self, from_, messages):
- '''Move messages to unsure.
-
- messages should be an iterable of (msgfrom, emailsubject,
- emaildate, msgid).
- '''
- idlist = [ str(item[3]) for item in messages ]
- print 'move from', from_, 'to unsure', idlist
- for msg_info in messages:
- if from_ == IS_HAM:
- self.removed_ham.append(msg_info[3])
- elif from_ == IS_SPAM:
- self.removed_spam.append(msg_info[3])
-
- if msg_info[3] in self.removed_unsure:
- self.removed_unsure.remove(msg_info[3])
-
- self.added_unsure.append(msg_info[3])
- if msg_info[3] in self.added_spam:
- self.added_spam.remove(msg_info[3])
-
- if msg_info[3] in self.added_ham:
- self.added_ham.remove(msg_info[3])
- continue
-
- self.UpdateViews()
- state.moveAndTrainMessages(idlist, from_, IS_UNSURE)
-
-
- def RemoveFromList(self, msgs, klass):
- self.tray.SetBeginUpdating()
- for view in self.views:
- if hasattr(view, 'list') and hasattr(view.list, 'DeselectAll'):
- view.list.DeselectAll()
- continue
-
- to_remove = []
- for msg_info in msgs:
- if klass == IS_HAM:
- self.removed_ham.append(msg_info[3])
- elif klass == IS_UNSURE:
- self.removed_unsure.append(msg_info[3])
- else:
- self.removed_spam.append(msg_info[3])
- to_remove.append(msg_info[3])
-
- self.UpdateViews()
- thread = threading.Thread(target = self._do_remove, args = (to_remove, klass))
- self.threads.append(thread)
- thread.setDaemon(True)
- thread.start()
-
-
- def _do_remove(self, to_remove, klass):
- for msg_info in to_remove:
- state.removeMessageFromCorpus(msg_info, klass)
-
- self.tray.SetEndUpdating()
-
-
- def GetWhiteList(self):
- if self.active == VIEW_WHITE:
- ret = { }
- for i, address in enumerate(state.address_classifier.keys(is_spam = False)):
- ret[i + 1] = unicode(address)
-
- self.white_list = ret
-
- return self.white_list
-
-
- def GetBlackList(self):
- if self.active == VIEW_BLACK:
- ret = { }
- for i, address in enumerate(state.address_classifier.keys(is_spam = True)):
- ret[i + 1] = unicode(address)
-
- self.black_list = ret
-
- return self.black_list
-
-
- def AddToWhitelist(self, email_list):
- map(self.AddEmailToWhitelist, email_list)
-
-
- def AddToBlacklist(self, email_list):
- map(self.AddEmailToBlacklist, email_list)
-
-
- def InBlacklist(self, email_list):
- results = { }
- for address in email_list:
- results[address] = state.address_classifier.spamprob(address) == 1.0
-
- return results
-
-
- def InWhitelist(self, email_list):
- results = { }
- for address in email_list:
- results[address] = state.address_classifier.spamprob(address) == 0.0
-
- return results
-
-
- def InAddressList(self, email_list):
- results = []
- for address in email_list:
- prob = state.address_classifier.spamprob(address)
- if prob == 1.0:
- isSpam = True
- elif prob == 0.0:
- isSpam = False
- else:
- isSpam = None
- results.append(isSpam)
-
- return results
-
-
- def DeleteFromWhitelist(self, email_list):
- for email in email_list:
-
- try:
- state.address_classifier.unlearn(str(email), False)
- continue
- except UnicodeEncodeError:
- continue
-
-
-
- state.address_classifier.store()
- self.UpdateViews()
-
-
- def MoveToBlacklist(self, email_list):
- for email in email_list:
-
- try:
- state.address_classifier.unlearn(str(email), True)
- except UnicodeEncodeError:
- pass
-
-
- try:
- state.address_classifier.learn(str(email), False)
- continue
- except UnicodeEncodeError:
- continue
-
-
-
- state.address_classifier.store()
-
-
- def DeleteFromBlacklist(self, email_list):
- for email in email_list:
-
- try:
- state.address_classifier.unlearn(str(email), True)
- continue
- except UnicodeEncodeError:
- continue
-
-
-
- state.address_classifier.store()
- self.UpdateViews()
-
-
- def MoveToWhitelist(self, email_list):
- for email in email_list:
-
- try:
- state.address_classifier.unlearn(str(email), False)
- except UnicodeEncodeError:
- pass
-
-
- try:
- state.address_classifier.learn(str(email), True)
- continue
- except UnicodeEncodeError:
- continue
-
-
-
- state.address_classifier.store()
-
-
- def AddEmailToBlacklist(self, email):
- for encoding in ('ascii', 'latin-1', 'koi8-r'):
-
- try:
- email = email.encode(encoding)
- except (UnicodeEncodeError, LookupError):
- continue
-
-
-
- try:
- state.address_classifier.forget(email)
- except UnicodeDecodeError:
- print >>sys.stderr, 'Bad address database; should be removed.'
-
-
- try:
- state.address_classifier.learn(email, True)
- except UnicodeDecodeError:
- print >>sys.stderr, 'Bad address database; should be removed.'
-
- state.address_classifier.store()
- self.UpdateViews()
-
-
- def AddEmailToWhitelist(self, email):
- for encoding in ('ascii', 'latin-1', 'koi8-r'):
-
- try:
- email = email.encode(encoding)
- except (UnicodeEncodeError, LookupError):
- continue
-
-
-
- try:
- state.address_classifier.forget(email)
- except UnicodeDecodeError:
- print >>sys.stderr, 'Bad address database; should be removed.'
-
-
- try:
- state.address_classifier.learn(email, False)
- except UnicodeDecodeError:
- print >>sys.stderr, 'Bad address database; should be removed.'
-
- state.address_classifier.store()
- self.UpdateViews()
-
-
- def ResetBlacklist(self):
- '''Remove all entries from the blacklist.
-
- If the entry has whitelist counts, too (less than the blacklist
- counts, obviously), then those are also removed.
- '''
- for address in state.address_classifier.keys(is_spam = True):
- state.address_classifier.forget(address)
-
- state.address_classifier.store()
-
-
- def ResetWhitelist(self):
- '''Remove all entries from the whitelist.
-
- If the entry has blacklist counts, too (less than the whitelist
- counts, obviously), then those are also removed.
- '''
- for address in state.address_classifier.keys(is_spam = False):
- state.address_classifier.forget(address)
-
- state.address_classifier.store()
-
-
- def ResetBayesianClassifier(self):
- '''Completely reset the bayesian training database.
-
- All future messages will be classified (by the bayesian
- system) as 0.5 until new training is carried out.'''
- all_words = tuple(state.bayes._wordinfokeys())
- for word in all_words:
- state.bayes._wordinfodel(word)
-
- if not len(state.bayes._wordinfokeys()) == 0:
- raise AssertionError, 'Reset did not work: %s keys left (%s)' % (len(state.bayes._wordinfokeys()), list(state.bayes._wordinfokeys()))
- state.bayes.nham = 0
- state.bayes.nspam = 0
- state.bayes.store()
-
-
- def ResetAll(self):
- '''Reset white and blacklists and bayesian database, and
- remove all cached mail.'''
- self.ResetWhitelist()
- self.ResetBlacklist()
- self.ResetBayesianClassifier()
- self._GetHam()
- self._GetUnsure()
- self._GetSpam()
- ham = self.ham_list.itervalues()
- unsure = self.unsure_list.itervalues()
- spam = self.spam_list.itervalues()
- for msg_info in ham:
- state.removeMessageFromCorpus(msg_info[3], IS_HAM)
-
- for msg_info in unsure:
- state.removeMessageFromCorpus(msg_info[3], IS_UNSURE)
-
- for msg_info in spam:
- state.removeMessageFromCorpus(msg_info[3], IS_SPAM)
-
-
-
- def GetInterceptedAppData(self, path):
- return (os.path.basename(path), '110,143', path)
-
-
- def GetSettings(self):
- return self.settings
-
-
- def SetSettings(self, block, modSubj, tag, lang, mailapps, auto_report, user_address, date_header, auto_update, startup, vertical, periodic, enable_period, period, notify_sound, balloons):
- self.settings.block_spam = block
- self.settings.modify_subject_tag = tag
- self.settings.modify_subject = modSubj
- self.settings.modify_subject_tag = tag
- for code, name in self.tray.languages.iteritems():
- if name == lang:
- self.settings.lang = code
- break
- continue
-
- self.settings.mailapps = mailapps
- self.settings.auto_bugreport = auto_report
- self.settings.user_address = user_address
- self.settings.date_header = date_header
- self.settings.automatically_update = auto_update
- self.settings.launch_on_startup = startup
- self.settings.split_vertically = vertical
- self.settings.enable_periodic = enable_period
- if not self.settings.enable_periodic:
- self.settings.periodic = []
- self.settings.not_periodic = []
- else:
- self.settings.periodic = periodic[0]
- self.settings.not_periodic = periodic[1]
- self.settings.period = period
- self.settings.notify_sound = notify_sound
- self.settings.enable_balloon_notifications = balloons
- self.UpdateViews()
-
-
- def UpdateAutomatically(self):
- return self.settings.automatically_update
-
-
- def isUpdateAvailable(self):
- vc = state.versioncontrol
- return vc.checkForUpdate()
-
-
-